package com.cnap.multiclouldmgmt;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;

/**
 * <类文件描述>
 *
 * @author xc
 **/
public class CommonModelTest {

    @Test
    void test() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, IntrospectionException, InvocationTargetException {
        Assertions.assertDoesNotThrow(()-> {
            List<String> packages = Arrays.asList(
                    "com.cnap.multiclouldmgmt.model.dockerHarborModel",
                    "com.cnap.multiclouldmgmt.model.k8sModels",
                    "com.cnap.multiclouldmgmt.model.k8sMonitorModels",
                    "com.cnap.multiclouldmgmt.model.log",
                    "com.cnap.multiclouldmgmt.model.vm",
                    "com.cnap.multiclouldmgmt.model.scale.db",
                    "com.cnap.multiclouldmgmt.model.scale.group",
                    "com.cnap.multiclouldmgmt.model.scale.policy",
                    "com.cnap.multiclouldmgmt.model.scale",
                    "com.cnap.multiclouldmgmt.model");
            for (String s : packages) {
                Class[] classes = getClasses(s);
                for (Class cls : classes) {
                    if (cls == null) {
                        continue;
                    }
                    Object obj = cls.newInstance();
                    Field[] fields = cls.getDeclaredFields();
                    for (Field field : fields) {
                        // 忽略jacoco添加的属性
                        if (field.isSynthetic()) {
                            continue;
                        }
                        // 忽略static字段
                        int modifiers = field.getModifiers();
                        if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) {
                            continue;
                        }

                        PropertyDescriptor descriptor = new PropertyDescriptor((String)field.getName(), cls);
                        Method get = descriptor.getReadMethod();
                        Method set = descriptor.getWriteMethod();
                        set.invoke(obj, get.invoke(obj));
                    }
                }
            }

        });
    }

    private Class[] getClasses(String packageName) throws IOException, ClassNotFoundException {
        Enumeration<URL> resources = CommonModelTest.class.getClassLoader().getResources(packageName.replaceAll("\\."
                , "/"));
        while (resources.hasMoreElements()) {
            URL url = resources.nextElement();
            String[] file = new File(url.getFile().replace("test-classes", "classes")).list();
            Class[] classes = new Class[file.length];
            for (int i = 0; i < file.length; i++) {
                if (!file[i].endsWith(".class")) {
                    continue;
                }
                Class cls = Class.forName(packageName + "." + file[i].replaceAll("\\.class", ""));
                if (cls.isEnum()) {
                    continue;
                }
                if (Modifier.isFinal(cls.getModifiers())) {
                    continue;
                }
                if (Modifier.isInterface(cls.getModifiers())) {
                    continue;
                }
                classes[i] = cls;
            }
            return classes;
        }
        return new Class[0];
    }

}
